package top.glkj.hms.utils;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.JpaSpecificationExecutor;
import top.glkj.hms.entity.BaseEntity;

import javax.persistence.criteria.Path;
import javax.persistence.criteria.Predicate;
import java.util.Map;

/**
 * @author : xgl
 * @version : 0.0.1
 * @date :2020/12/21 1:34
 */
public class GlUtils<T extends BaseEntity,E extends JpaSpecificationExecutor<T>& JpaRepository<T,Long>>{

    private int mapIndex = StaticValue.ZERO;


    public GlUtils() {
    }
    public Result getAllByPageAndSize(int page, int size,E e){
        Pageable pageable = PageRequest.of(pageValue(page)-1, sizeValue(size));
        return this.getNotNullPageResult( e.findAll(pageable));
    }
    public Result getAllByPageAndSizeAndArgs(int page, int size, String argName, String value, E e){
        Pageable pageable = PageRequest.of(pageValue(page), sizeValue(size));
        Specification<T> specification = (root, query, cb) -> {
            /* 1、获取比较属性 */
            Path<Object> compare = root.get(argName);
            Path<Object> status = root.get("status");
            Predicate predicateStatus = cb.equal(status, Status.Enable);
            Predicate predicateCompare = cb.like(compare.as(String.class), "%" + value + "%");
            return cb.and(predicateCompare, predicateStatus);
        };
        return this.getNotNullPageResult( e.findAll(specification, pageable));
    }
    public Result getAllByPageAndSizeAndAnyArgs(int page, int size, Map<String, String> args,E e){
        Pageable pageable = PageRequest.of(pageValue(page), sizeValue(size));
        Specification<T> specification = (root, query, cb) -> {
            /* 1、获取比较属性 */
            Predicate[] predicateList = new Predicate[args.size()+1];
            mapIndex = 0;
            args.forEach((key, value) -> {
                predicateList[mapIndex] = (cb.like(root.get(key).as(String.class), "%" + value + "%"));
                mapIndex++;
            });

            Path<Object> status = root.get("status");
            Predicate predicateStatus = cb.equal(status, Status.Enable);
            predicateList[args.size()] = predicateStatus;
            return  cb.and(predicateList);
        };

        return getNotNullPageResult(e.findAll(specification, pageable));
    }

    /**
     * 检查page的值是否符合条件，不符合自动筛选
     *
     * @param page page值
     * @return page
     */
    private int pageValue(int page) {
        if (page < StaticValue.ONE) {
            return StaticValue.ONE;
        }
        return page;
    }

    /**
     * 检查size的值是否符合条件，不符合自动筛选
     *
     * @param size 页面大小
     * @return 页面大小 size
     */
    private int sizeValue(int size) {
        if (size < StaticValue.FIVE) {
            return StaticValue.FIVE;
        } else if (size > StaticValue.HUNDRED) {
            return StaticValue.HUNDRED;
        }
        return size;
    }

    private  Result getNotNullPageResult(Page<T> all){
        return all.isEmpty()? ResultFactory.isException(StaticValue.DATA_NOT_FOUND) : ResultFactory.isSuccess(StaticValue.GET_DATA_SUCCESS, all);
    }

}
